package com.xingchi.tornado.utils;

import org.springframework.core.ResolvableType;
import org.springframework.util.ClassUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 泛型处理工具类
 *
 * @author xiaoya
 * @date 2024/3/15 13:37
 */
public class GenericTypeUtils {

    /**
     * 缓存
     */
    private static final Map<String, Class<?>> CACHE_CLASS = new ConcurrentHashMap<>(8);

    /**
     * 获取指定类在父类中的泛型类型
     *
     * @param clazz       基础类
     * @param supperClass 父类或父接口
     * @param index       泛型参数索引
     * @return 泛型参数类
     */
    public static Class<?> getSuperClassGenericType(Class<?> clazz, Class<?> supperClass, int index) {

        if (clazz == null) {
            throw new IllegalArgumentException("基础类不能为空");
        }

        if (supperClass == null) {
            throw new IllegalArgumentException("父类或父接口不能为空");
        }

        if (!supperClass.isAssignableFrom(clazz)) {
            throw new IllegalArgumentException("基础类必须是父类或父接口的子类");
        }

        return CACHE_CLASS.computeIfAbsent(clazz.getName() + ":" + supperClass.getName() + ":" + index, key -> {
            return ResolvableType.forClass(supperClass, clazz).getGeneric(index).resolve();
        });
    }

    /**
     * 创建指定类的实例
     *
     * @param clazz       基础类
     * @param supperClass 父类或父接口
     * @param index       泛型参数索引
     * @return 泛型参数类
     */
    public static Object createInstance(Class<?> clazz, Class<?> supperClass, int index) {
        Class<?> genericType = getSuperClassGenericType(clazz, supperClass, index);
        if (genericType == null) {
            return null;
        }

        try {
            // 根据无参构造方法创建对象实例
            return genericType.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

}
